#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
WMS系统分环境打包脚本
每个应用使用对应的虚拟环境进行打包
"""

import os
import sys
import subprocess
import shutil
from pathlib import Path
from datetime import datetime

def print_header(title):
    """打印标题"""
    print("\n" + "="*60)
    print(f"  {title}")
    print("="*60)

def print_step(step, description):
    """打印步骤"""
    print(f"\n{step}. {description}")
    print("-" * 40)

def run_command_in_env(cmd, env_path, description):
    """在指定虚拟环境中运行命令"""
    if os.name == 'nt':  # Windows
        python_exe = env_path / "Scripts" / "python.exe"
        pip_exe = env_path / "Scripts" / "pip.exe"
        pyinstaller_exe = env_path / "Scripts" / "pyinstaller.exe"
    else:  # Linux/Mac
        python_exe = env_path / "bin" / "python"
        pip_exe = env_path / "bin" / "pip"
        pyinstaller_exe = env_path / "bin" / "pyinstaller"
    
    # 替换命令中的python和pyinstaller路径
    if cmd.startswith('python '):
        cmd = cmd.replace('python ', f'"{python_exe}" ', 1)
    elif cmd.startswith('pip '):
        cmd = cmd.replace('pip ', f'"{pip_exe}" ', 1)
    elif cmd.startswith('pyinstaller '):
        cmd = cmd.replace('pyinstaller ', f'"{pyinstaller_exe}" ', 1)
    
    print(f"环境: {env_path.name}")
    print(f"执行: {cmd}")
    
    try:
        result = subprocess.run(cmd, shell=True, check=True, 
                              capture_output=True, text=True, encoding='utf-8')
        print(f"✅ {description} 成功")
        return True
    except subprocess.CalledProcessError as e:
        print(f"❌ {description} 失败")
        if e.stderr:
            print(f"错误: {e.stderr}")
        return False
    except Exception as e:
        print(f"❌ {description} 异常: {e}")
        return False

def check_environments():
    """检查各个虚拟环境"""
    print_step("1", "检查虚拟环境")
    
    environments = {
        "主程序环境": {
            "path": Path("wms_clean_env"),
            "requirements": "requirements_minimal.txt",
            "description": "用于打包WMS主程序"
        },
        "服务管理器环境": {
            "path": Path("service_manager_env"),
            "requirements": "requirements_clean.txt", 
            "description": "用于打包服务配置管理器"
        },
        "完整服务环境": {
            "path": Path("clean_env_new"),
            "requirements": "requirements_wms_service.txt",
            "description": "用于打包WMS服务和客户端"
        }
    }
    
    missing_envs = []
    for name, config in environments.items():
        env_path = config["path"]
        if not env_path.exists():
            missing_envs.append(name)
            print(f"❌ {name}: {env_path} 不存在")
        else:
            python_exe = env_path / "Scripts" / "python.exe"
            if python_exe.exists():
                print(f"✅ {name}: {env_path}")
            else:
                missing_envs.append(name)
                print(f"❌ {name}: Python可执行文件不存在")
    
    if missing_envs:
        print(f"\n缺少环境: {', '.join(missing_envs)}")
        return False
    
    return True

def setup_environments():
    """设置各个虚拟环境的依赖"""
    print_step("2", "设置虚拟环境依赖")
    
    env_configs = [
        {
            "name": "主程序环境",
            "path": Path("wms_clean_env"),
            "requirements": "requirements_minimal.txt"
        },
        {
            "name": "服务管理器环境", 
            "path": Path("service_manager_env"),
            "requirements": "requirements_clean.txt"
        },
        {
            "name": "完整服务环境",
            "path": Path("clean_env_new"),
            "requirements": "requirements_wms_service.txt"
        }
    ]
    
    success_count = 0
    for config in env_configs:
        print(f"\n设置 {config['name']}...")
        
        # 检查requirements文件是否存在
        req_file = Path(config['requirements'])
        if not req_file.exists():
            print(f"❌ 依赖文件不存在: {config['requirements']}")
            continue
        
        # 安装依赖
        if run_command_in_env(
            f"pip install -r {config['requirements']}",
            config['path'],
            f"{config['name']}依赖安装"
        ):
            success_count += 1
    
    return success_count == len(env_configs)

def build_main_application():
    """打包主程序 - 使用wms_clean_env"""
    print_step("3", "打包主程序 (WMS Sample)")
    
    env_path = Path("wms_clean_env")
    
    # 使用build_for_deployment.py，但指定环境
    return run_command_in_env(
        "python build_for_deployment.py",
        env_path,
        "主程序打包"
    )

def build_client_application():
    """打包客户端程序 - 使用clean_env_new"""
    print_step("4", "打包客户端程序 (WMS Client)")
    
    env_path = Path("clean_env_new")
    
    # 使用build_client.py，但指定环境
    return run_command_in_env(
        "python build_client.py",
        env_path,
        "客户端程序打包"
    )

def build_service_config_manager():
    """打包服务配置管理器 - 使用service_manager_env"""
    print_step("5", "打包服务配置管理器")
    
    env_path = Path("service_manager_env")
    
    return run_command_in_env(
        "pyinstaller --clean service_config_manager.spec",
        env_path,
        "服务配置管理器打包"
    )

def build_wms_service():
    """打包WMS服务 - 使用clean_env_new"""
    print_step("6", "打包WMS服务")
    
    env_path = Path("clean_env_new")
    
    return run_command_in_env(
        "pyinstaller --clean wms_service.spec",
        env_path,
        "WMS服务打包"
    )

def clean_build_directories():
    """清理构建目录"""
    print_step("0", "清理构建目录")
    
    dirs_to_clean = ['build', 'dist']
    for dir_name in dirs_to_clean:
        if Path(dir_name).exists():
            shutil.rmtree(dir_name)
            print(f"✅ 清理目录: {dir_name}")
        else:
            print(f"ℹ️ 目录不存在: {dir_name}")
    
    return True

def create_environment_summary():
    """创建环境使用总结"""
    print_step("7", "环境使用总结")
    
    summary = """
📋 各应用使用的虚拟环境总结:

1️⃣ 主程序 (WMS Sample)
   环境: wms_clean_env/
   依赖: requirements_minimal.txt
   包含: FastAPI, SQLAlchemy, PyInstaller (最小依赖)

2️⃣ 客户端程序 (WMS Client)  
   环境: clean_env_new/
   依赖: requirements_wms_service.txt
   包含: 完整依赖 + GUI库

3️⃣ 服务配置管理器
   环境: service_manager_env/
   依赖: requirements_clean.txt
   包含: PyWin32, PyInstaller, Requests (精简依赖)

4️⃣ WMS服务
   环境: clean_env_new/
   依赖: requirements_wms_service.txt
   包含: 完整的服务端依赖

🎯 优势:
- 每个应用依赖隔离，避免冲突
- 打包体积最小化
- 环境纯净，打包成功率高
"""
    
    print(summary)
    return True

def create_deployment_package():
    """创建最终部署包"""
    print_step("8", "创建部署包")
    
    try:
        # 运行部署包创建脚本
        result = subprocess.run(
            "python tools/create_deployment_package.py",
            shell=True,
            check=True,
            capture_output=True,
            text=True,
            encoding='utf-8'
        )
        
        print("✅ 部署包创建成功")
        print("📦 部署包包含:")
        print("  - 服务配置管理器 (service_config_manager.exe)")
        print("  - WMS服务 (wms_service.exe)")
        print("  - 启动脚本和配置文件")
        print("  - 使用说明文档")
        
        return True
        
    except subprocess.CalledProcessError as e:
        print(f"❌ 部署包创建失败: {e}")
        if e.stderr:
            print(f"错误信息: {e.stderr}")
        return False
    except Exception as e:
        print(f"❌ 部署包创建异常: {e}")
        return False

def verify_packages():
    """验证打包结果"""
    print_step("9", "验证打包结果")
    
    expected_outputs = [
        {
            "name": "主程序",
            "pattern": "WMS_Sample_v2.1.0_Production_*",
            "exe_path": "WMS_Sample.exe"
        },
        {
            "name": "客户端程序", 
            "pattern": "WMS_Client_v2.1.0_Production_*",
            "exe_path": "WMS_Client.exe"
        },
        {
            "name": "服务配置管理器",
            "pattern": "dist/service_config_manager",
            "exe_path": "service_config_manager.exe"
        },
        {
            "name": "WMS服务",
            "pattern": "dist/wms_service", 
            "exe_path": "wms_service.exe"
        },
        {
            "name": "部署包",
            "pattern": "deployments/WMS_ServiceManager_*",
            "exe_path": "service_config_manager.exe"
        }
    ]
    
    verification_results = []
    
    for output in expected_outputs:
        if output["pattern"].startswith("dist/"):
            # 直接检查dist目录
            base_path = Path(output["pattern"])
            exe_file = base_path / output["exe_path"]
        else:
            # 查找匹配的目录
            matching_dirs = list(Path('.').glob(output["pattern"]))
            if matching_dirs:
                latest_dir = max(matching_dirs, key=lambda p: p.stat().st_mtime)
                exe_file = latest_dir / output["exe_path"]
            else:
                exe_file = None
        
        if exe_file and exe_file.exists():
            verification_results.append((output["name"], "✅ 通过"))
        else:
            verification_results.append((output["name"], "❌ 失败"))
    
    # 输出验证结果
    print("\n验证结果:")
    for name, result in verification_results:
        print(f"  {name:<15}: {result}")
    
    success_count = sum(1 for _, result in verification_results if "✅" in result)
    total_count = len(verification_results)
    
    print(f"\n总体结果: {success_count}/{total_count} 个应用打包成功")
    return success_count == total_count

def main():
    """主函数"""
    print_header("WMS系统分环境打包")
    print("使用专用虚拟环境确保依赖隔离")
    
    start_time = datetime.now()
    
    # 执行打包流程
    steps = [
        check_environments,
        clean_build_directories, 
        setup_environments,
        build_main_application,
        build_client_application,
        build_service_config_manager,
        build_wms_service,
        create_environment_summary,
        create_deployment_package,
        verify_packages
    ]
    
    for i, step_func in enumerate(steps):
        try:
            if not step_func():
                print(f"\n❌ 步骤 {i} 失败，打包中止")
                return False
        except Exception as e:
            print(f"\n❌ 步骤 {i} 异常: {e}")
            return False
    
    end_time = datetime.now()
    duration = end_time - start_time
    
    print_header("打包完成")
    print(f"✅ 所有应用打包成功!")
    print(f"⏱️ 总耗时: {duration}")
    print(f"🎯 每个应用都使用了专用的虚拟环境")
    
    return True

if __name__ == "__main__":
    success = main()
    input("\n按回车键退出...")
    sys.exit(0 if success else 1) 